import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class ScoreSystem {
    private List<Student> studentList = new ArrayList<>();
    private List<Course> courseList = new ArrayList<>();
    private List<Score> scoreList = new ArrayList<>();

    // 学生信息录入
    public void addStudent(Student student) throws InfoDuplicateException {
        for (Student s : studentList) {
            if (s.getStuId().equals(student.getStuId())) {
                throw new InfoDuplicateException("学号" + student.getStuId() + "已存在");
            }
        }
        studentList.add(student);
    }

    // 课程信息录入
    public void addCourse(Course course) throws InfoDuplicateException {
        for (Course c : courseList) {
            if (c.getCourseId().equals(course.getCourseId())) {
                throw new InfoDuplicateException("课程编号" + course.getCourseId() + "已存在");
            }
        }
        courseList.add(course);
    }

    // 根据学号查询学生
    private Student findStudentByStuId(String stuId) throws InfoNotFoundException {
        for (Student s : studentList) {
            if (s.getStuId().equals(stuId)) {
                return s;
            }
        }
        throw new InfoNotFoundException("学号" + stuId + "未录入");
    }

    // 根据课程编号查询课程
    private Course findCourseByCourseId(String courseId) throws InfoNotFoundException {
        for (Course c : courseList) {
            if (c.getCourseId().equals(courseId)) {
                return c;
            }
        }
        throw new InfoNotFoundException("课程编号" + courseId + "未录入");
    }

    // 添加成绩
    public void addScore(String stuId, String courseId, double score) throws Exception {
        Student student = findStudentByStuId(stuId);
        Course course = findCourseByCourseId(courseId);
        for (Score sc : scoreList) {
            if (sc.getStudent().getStuId().equals(stuId) && sc.getCourse().getCourseId().equals(courseId)) {
                throw new InfoDuplicateException("该学生的此课程成绩已存在");
            }
        }
        scoreList.add(new Score(student, course, score));
    }

    // 查询成绩
    public double queryScore(String stuId, String courseId) throws InfoNotFoundException {
        findStudentByStuId(stuId);
        findCourseByCourseId(courseId);
        for (Score sc : scoreList) {
            if (sc.getStudent().getStuId().equals(stuId) && sc.getCourse().getCourseId().equals(courseId)) {
                return sc.getScore();
            }
        }
        throw new InfoNotFoundException("该学生的此课程暂无成绩");
    }

    // 计算4.0满GPA
    public double calculateGPA(String stuId) throws InfoNotFoundException {
        findStudentByStuId(stuId);
        double totalPoint = 0.0;
        int totalCredit = 0;
        for (Score sc : scoreList) {
            if (sc.getStudent().getStuId().equals(stuId)) {
                Course course = sc.getCourse();
                totalCredit += course.getCredit();
                double point = sc.getScore() >= 90 ? 4.0 :
                        sc.getScore() >= 80 ? 3.0 :
                                sc.getScore() >= 70 ? 2.0 :
                                        sc.getScore() >= 60 ? 1.0 : 0.0;
                totalPoint += point * course.getCredit();
            }
        }
        return totalCredit == 0 ? 0.0 : Math.round((totalPoint / totalCredit) * 100) / 100.0;
    }

    // 存储到文件
    public void saveToFile(String filePath) throws IOException {
        FileWriter writer = new FileWriter(filePath);
        writer.write("===== 学生信息 =====\n");
        for (Student s : studentList) {
            writer.write("学号：" + s.getStuId() + "，姓名：" + s.getName() + "，班级：" + s.getClazz() + "\n");
        }
        writer.write("\n===== 课程信息 =====\n");
        for (Course c : courseList) {
            writer.write("课程编号：" + c.getCourseId() + "，课程名称：" + c.getCourseName() + "，学分：" + c.getCredit() + "\n");
        }
        writer.write("\n===== 成绩及GPA信息 =====\n");
        for (Student s : studentList) {
            writer.write("\n学生：" + s.getName() + "（学号：" + s.getStuId() + "）\n");
            try {
                writer.write("GPA（4.0满）：" + calculateGPA(s.getStuId()) + "\n");
            } catch (InfoNotFoundException e) {
                writer.write("GPA（4.0满）：" + e.getMessage() + "\n");
            }
            writer.write("课程成绩：\n");
            boolean hasScore = false;
            for (Score sc : scoreList) {
                if (sc.getStudent().getStuId().equals(s.getStuId())) {
                    Course c = sc.getCourse();
                    writer.write("  - " + c.getCourseName() + "：" + sc.getScore() + "分\n");
                    hasScore = true;
                }
            }
            if (!hasScore) {
                writer.write("  - 暂无成绩\n");
            }
        }
        writer.close();
    }
}